// MyGraphFrame.cpp : implementation file
//

#include "stdafx.h"
#include "waveeditor.h"
#include "PictureRangeDialog.h"	
#include "waveeditordoc.h"
#include "MainFrm.h"
#include "MyGraphFrame.h"
#include "MyGraphView.h"
#include "MyGraphButtonView.h"	
#include "MyGraphClockView.h"	
#include "MyGraphInfoView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// MyGraphFrame

IMPLEMENT_DYNCREATE(ChildGraphFrame, CMDIChildWnd)

ChildGraphFrame::ChildGraphFrame()
{
}

ChildGraphFrame::~ChildGraphFrame()
{
}


BEGIN_MESSAGE_MAP(ChildGraphFrame, CMDIChildWnd)
	//{{AFX_MSG_MAP(MyGraphFrame)
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
	ON_COMMAND(ID_SHIFTRIGHT, OnShiftRight)
	ON_COMMAND(ID_SHIFTLEFT, OnShiftLeft)
	ON_COMMAND(ID_ZOOMIN, OnZoomin)
	ON_COMMAND(ID_ZOOMOUT, OnZoomout)
	ON_COMMAND(ID_CHOOSE_COLOR, OnChooseColor)
	ON_COMMAND(ID_REMOVESIGNAL, OnRemoveSignal)
	ON_COMMAND(ID_ADDSIGNALS, OnAddSignals)
	ON_COMMAND(ID_REFRESH, OnRefresh)
	ON_COMMAND(ID_SAVE_SCREENSHOT, SaveGraphScreenShot)
	ON_COMMAND(ID_SAVE_WHOLE_GRAPH, SaveWholeGraphChart)
	ON_COMMAND(ID_GROUP_WAVES, OnGroupWaves)
	ON_COMMAND(ID_SET_HIGHLIGHTING_RULES, OnSetHighlightingRules)
	ON_COMMAND(ID_DELETE_PERMANENTLY, OnDeletePermanently)
	ON_COMMAND(ID_MS_US, OnChangeMsUs)
	ON_COMMAND(ID_RELOAD_LOG, OnReloadLogWithChosenProperties)
	ON_COMMAND(ID_CUT_RETURN_FREE_SPACE, OnCutReturnFreeSpace)
	ON_COMMAND(ID_NORMALTOOL, OnGraphNormalTool)
	ON_COMMAND(ID_ZOOMTOOL, OnGraphZoomTool)
	ON_COMMAND(ID_SCROLLTOOL, OnGraphScrollTool)
	ON_COMMAND(ID_SHOW_GRID, OnShowGrid)

	//ON_COMMAND(ID_SCROLL_VERT, OnScrollVert)
	ON_UPDATE_COMMAND_UI( ID_MS_US, OnUpdateMsUsButton )
	ON_UPDATE_COMMAND_UI( ID_RELOAD_LOG, OnUpdateReloadButton )
	ON_WM_SIZING()
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// MyGraphFrame message handlers

BOOL ChildGraphFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
{
	CurrentDocument = (ZWaveeditorDoc*)(pContext->m_pCurrentDoc);
	SelectedScenario = CurrentDocument->selectedscenario;
	graphtooltype	=	NORMALTOOL;

	BOOL res =  mysplit.CreateStatic(this,2,2);
	mysplit.CreateView(0,0,RUNTIME_CLASS(GraphInfoView), CSize(100,50),pContext);

	mysplit.CreateView(0,1,RUNTIME_CLASS(GraphClockView), CSize(0,50),pContext);
	mysplit.CreateView(1,0,RUNTIME_CLASS(GraphButtonView), CSize(100,0),pContext);
	mysplit.CreateView(1,1,RUNTIME_CLASS(GraphView), CSize(0,0),pContext);
	mysplit.SetScrollStyle(WS_VSCROLL|WS_HSCROLL);

	return res;
}

BOOL ChildGraphFrame::PreCreateWindow(CREATESTRUCT& cs) 
{
	// TODO: Add your specialized code here and/or call the base class
	CRect framerect;
	CRect srect;
	CRect trect;

	ParentMainFrame *pMainFrame = (ParentMainFrame *) AfxGetMainWnd();
	pMainFrame->GetClientRect(&framerect);
	pMainFrame->m_wndStatusBar	.GetWindowRect(&srect);
	pMainFrame->m_wndToolBar	.GetWindowRect(&trect);
	int	height	=	framerect.Height()-srect.Height()*2-trect.Height();
	cs.x		=	framerect.right/4;
	cs.y		=	framerect.top;
	cs.cx		=	framerect.right-cs.x;
	cs.cy		=	height - DEBUG_WINDOW_HEIGHT;
	cs.style	&= ~(/*WS_MAXIMIZEBOX|*/WS_MINIMIZEBOX );//|WS_SYSMENU );
	cs.style	=	cs.style|WS_MAXIMIZEBOX;
	
	return CMDIChildWnd::PreCreateWindow(cs);
}

int ChildGraphFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	long Result = -1;
	if (CMDIChildWnd::OnCreate(lpCreateStruct) != -1 &&
		m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC ) && 
		m_wndToolBar.Load24BitToolBar( IDR_GRAPHVIEWFRAME, IDB_GRAPH_FRAME_TOOLBAR_DISABLED ))
	{
		CArray<UINT> IDs;
		IDs.Add( ID_NORMALTOOL );
		IDs.Add( ID_SCROLLTOOL );
		IDs.Add( ID_ZOOMTOOL );
		IDs.Add( ID_ALWAYS_SHOW_HINT );
		IDs.Add( ID_SHOW_GRID );
		m_wndToolBar.SetButtonsStyle( IDs, TBBS_CHECKBOX );

		IDs.RemoveAll();
		IDs.Add( ID_NORMALTOOL );
		m_wndToolBar.SetButtonsStyle( IDs, TBBS_CHECKED );

		Result = 0;
		// TODO: Delete these three lines if you don't want the toolbar to
		//  be dockable
		m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
		EnableDocking(CBRS_ALIGN_ANY);
		DockControlBar(&m_wndToolBar);

		CToolBar   my_ToolBar;
		 my_ToolBar.Create(this);
		 my_ToolBar.LoadToolBar(IDR_GRAPHVIEWFRAME);
		 const UINT but[1] = {ID_SHOW_GRID};
		 my_ToolBar.SetButtons(but, 22);
	}
	else
	{
		TRACE0("Failed to create\n");
	}
	return Result;
}


void ChildGraphFrame::OnGraphNormalTool()
{
	// TODO: Add your command handler code here
	CArray<UINT> IDs;

	IDs.Add( ID_SCROLLTOOL );
	IDs.Add( ID_ZOOMTOOL );
	m_wndToolBar.SetButtonsStyle( IDs, TBBS_CHECKBOX );

	IDs.RemoveAll();
	IDs.Add( ID_NORMALTOOL );
	m_wndToolBar.SetButtonsStyle( IDs, TBBS_CHECKED );

	graphtooltype	=	NORMALTOOL;
}

void ChildGraphFrame::OnGraphZoomTool()
{
	// TODO: Add your command handler code here
	CArray<UINT> IDs;
	IDs.Add( ID_SCROLLTOOL );
	IDs.Add( ID_NORMALTOOL );
	m_wndToolBar.SetButtonsStyle( IDs, TBBS_CHECKBOX );

	IDs.RemoveAll();
	IDs.Add( ID_ZOOMTOOL );
	m_wndToolBar.SetButtonsStyle( IDs, TBBS_CHECKED );
	
	graphtooltype	=	ZOOMTOOL;
}

void ChildGraphFrame::OnGraphScrollTool()
{
	// TODO: Add your command handler code here
	CArray<UINT> IDs;
	IDs.Add( ID_ZOOMTOOL );
	IDs.Add( ID_NORMALTOOL );
	m_wndToolBar.SetButtonsStyle( IDs, TBBS_CHECKBOX );

	IDs.RemoveAll();
	IDs.Add( ID_SCROLLTOOL );
	m_wndToolBar.SetButtonsStyle( IDs, TBBS_CHECKED );
	graphtooltype	=	SCROLLTOOL;
}

void ChildGraphFrame::OnUpdateMsUsButton( CCmdUI* pCmdUI )
{
	if ( GetGraphView()->GetOriginalTimeType() == "ms" )
	{
		m_wndToolBar.GetToolBarCtrl().HideButton( ID_MS_US );
	}
}

void ChildGraphFrame::OnUpdateReloadButton( CCmdUI* pCmdUI )
{
	if ( GetGraphView()->SourceIsLog() == false )
	{
		m_wndToolBar.GetToolBarCtrl().HideButton( ID_RELOAD_LOG );
	}
}

CWnd* ChildGraphFrame::GetGraphWnd()
{
	return mysplit.GetPane(1,1);
}

CWnd* ChildGraphFrame::GetInfoWnd()
{
	return mysplit.GetPane(0,0);
}

CWnd* ChildGraphFrame::GetClockWnd()
{
	return mysplit.GetPane(0,1);
}

CWnd* ChildGraphFrame::GetGraphBut(void)
{
	return mysplit.GetPane(1,0);
}

void ChildGraphFrame::OnShiftRight()
{
	GetGraphView()->OnShift( RIGHT );
}

void ChildGraphFrame::OnShiftLeft()
{
	GetGraphView()->OnShift( LEFT );
}

void ChildGraphFrame::OnZoomin()
{
	GetGraphView()->OnZoomin();
}

void ChildGraphFrame::OnZoomout()
{
	GetGraphView()->OnZoomout();
}

void ChildGraphFrame::OnChooseColor()
{
	GetGraphView()->OnChooseColor();
}

void ChildGraphFrame::OnChangeMsUs()
{
	GetGraphView()->OnChangeMsUs();
}

void ChildGraphFrame::OnRemoveSignal()
{
	GetGraphView()->OnRemoveSignals();
}

void ChildGraphFrame::OnDeletePermanently()
{
	GetGraphView()->OnDeletePermanently();
}

void ChildGraphFrame::OnAddSignals()
{
	GetGraphView()->OnAddSignals();
}

void ChildGraphFrame::OnRefresh() 
{
	GetGraphView()->Refresh();
}

void ChildGraphFrame::OnGroupWaves()
{
	GetGraphView()->OnGroupWaves();
}

void ChildGraphFrame::OnSetHighlightingRules()
{
	GetGraphView()->OnSetHighlightingRules();
}

void ChildGraphFrame::OnReloadLogWithChosenProperties()
{
	GetGraphView()->OnReloadLogWithChosenProperties();
}

void ChildGraphFrame::OnCutReturnFreeSpace()
{
	CurrentDocument->_script[SelectedScenario]->CutReturnFreeSpace();
	CString GroupName	=	CurrentDocument->_script[SelectedScenario]->mygraphdata.GetGroupName();
	CurrentDocument->OnGraphView( SelectedScenario, GroupName );
}

GraphView * ChildGraphFrame::GetGraphView()
{
	return (GraphView *)GetGraphWnd();
}

void ChildGraphFrame::SaveWholeGraphChart()
{
	CurrentDocument->StatusList.ClearLog();
	CImage ImageForSave;
	HDC hImageForSaveDC;
	__int64 StartPosition;
	__int64 EndPosition;
	bool Success = true;

	if ( GetPositionForPicture( StartPosition, EndPosition ) == true )
	{
		CImage *GraphImage = new CImage();
		CImage *GraphClockImage = new CImage();
		CImage *GraphButtonImage = new CImage();

		__int64 HorizontalSize = CurrentDocument->_script[ SelectedScenario ]->mygraphdata.GetSizeInPixels( EndPosition - StartPosition );
		int GraphButtonImageSize = ((GraphButtonView*)GetGraphBut())->GetHorizontalSizeForButtonImage( GraphButtonImage );
		HorizontalSize = min ( HorizontalSize, ((unsigned int)(-1))/2 - GraphButtonImageSize ); 
		int VerticalSize= CurrentDocument->_script[ SelectedScenario ]->globalsignals->GetOnlySignalTotalDelta();

		if ( GraphImage->Create( (long)HorizontalSize, VerticalSize, 24 ) == TRUE &&
			GraphClockImage->Create( (long)HorizontalSize, 50, 24 ) == TRUE &&
			GraphButtonImage->Create( ((GraphButtonView*)GetGraphBut())->GetHorizontalSizeForButtonImage( GraphButtonImage ), VerticalSize, 24 ) == TRUE &&
			ImageForSave.Create( HorizontalSize = GraphImage->GetWidth() + GraphButtonImage->GetWidth(), VerticalSize = GraphImage->GetHeight() + GraphClockImage->GetHeight(), 24 ) == TRUE )
		{
			CRect RectForCopy;
			CString FileName = GetNameForFile();
			if ( FileName != "" )
			{
				CString GroupName	=	CurrentDocument->_script[SelectedScenario]->mygraphdata.GetGroupName();
				graphdata ImageGraphData;
				CurrentDocument->_script[ SelectedScenario ]->SetGraphDataTotalSize( &ImageGraphData, GroupName );
				CurrentDocument->_script[ SelectedScenario ]->FirstInitGraphData( &ImageGraphData, GroupName, StartPosition, EndPosition - StartPosition, GraphImage->GetWidth() );

				GetGraphView()->GetWholeGraphChart( GraphImage, &ImageGraphData );
				((GraphClockView*)GetClockWnd())->GetWholeGraphClockChart( GraphClockImage, &ImageGraphData );
				((GraphButtonView*)GetGraphBut())->DrawSignalNamesPanelIntoImage( GraphButtonImage );

				hImageForSaveDC = ImageForSave.GetDC();
				GetGraphView()->DrawRectangleInColor( CDC::FromHandle( hImageForSaveDC ),
		   											CRect( 0, 0, GraphButtonImage->GetWidth(), GraphClockImage->GetHeight() ),
													WHITE, 
													WHITE );
				RectForCopy = CRect( GraphButtonImage->GetWidth(), 0, (long)HorizontalSize, GraphClockImage->GetHeight() );
				GraphClockImage->BitBlt( hImageForSaveDC, RectForCopy, CPoint(0, 0), SRCCOPY);
				RectForCopy = CRect( 0, GraphClockImage->GetHeight(), GraphButtonImage->GetWidth(), VerticalSize );
				GraphButtonImage->BitBlt( hImageForSaveDC, RectForCopy, CPoint(0, 0), SRCCOPY);
				RectForCopy = CRect( GraphButtonImage->GetWidth(), GraphClockImage->GetHeight(), (long)HorizontalSize, VerticalSize );
				GraphImage->BitBlt( hImageForSaveDC, RectForCopy, CPoint(0, 0), SRCCOPY);
				ImageForSave.ReleaseDC();
				if ( ImageForSave.Save( FileName, Gdiplus::ImageFormatPNG) != S_OK )
				{
					Success = false;
				}
				else
				{
					CurrentDocument->StatusList.AddMessage("Saving was completed successfully");
				}
			}
		}
		else
		{
			Success = false;
		}
		CurrentDocument->UpdateAllViews(0);
		delete GraphImage;
		delete GraphClockImage;
		delete GraphButtonImage;
	}
	if ( Success == false )
	{
		CurrentDocument->StatusList.AddMessage("ERROR: Saving was not completed cause of unexpected error");
	}
	return;
}

void ChildGraphFrame::SaveGraphScreenShot()
{
	CImage ImageForSave;
	CDC *GraphViewDC = GetDC();
	CRect GraphWindowSizes;
	CRect GraphToolBarSizes;
	
	GetClientRect(&GraphWindowSizes);
	int HeightOfHorizontalScrollBar = GetSystemMetrics( SM_CYHSCROLL );
	int WidthOfVerticalScrollBar = GetSystemMetrics( SM_CXVSCROLL );
	m_wndToolBar.GetClientRect( &GraphToolBarSizes );

	ImageForSave.Create( GraphWindowSizes.right - WidthOfVerticalScrollBar - 1,
						GraphWindowSizes.bottom - GraphToolBarSizes.bottom - HeightOfHorizontalScrollBar - 2,
						24 );
	CDC *ImageForSaveDC = CDC::FromHandle( ImageForSave.GetDC() );
	ImageForSaveDC->BitBlt( 0,
							0,
							GraphWindowSizes.right - WidthOfVerticalScrollBar - 1,
							GraphWindowSizes.bottom - GraphToolBarSizes.bottom - HeightOfHorizontalScrollBar - 2,
							GraphViewDC,
							0,
							GraphToolBarSizes.bottom + 1,
							SRCCOPY);

    CString FileName = GetNameForFile();
    if ( FileName != "" && ImageForSave.Save( FileName, Gdiplus::ImageFormatPNG) != S_OK )
    {
	    ((ZWaveeditorDoc*)GetActiveDocument())->StatusList.ClearLog();
	    ((ZWaveeditorDoc*)GetActiveDocument())->StatusList.AddMessage("Saving was not completed cause of unexpected error");
    }

	ImageForSave.ReleaseDC();
	ReleaseDC( GraphViewDC );

	return;
}

CString ChildGraphFrame::GetNameForFile()
{
	CString  FileName = "";
	ZWaveeditorApp	*pWinapp	=	(ZWaveeditorApp*) AfxGetApp();
	CString outputdir			=	pWinapp->OutputDirectory;
	outputdir					+=	"\\*.png";
	char Filters[]= "PNG (*.png)|*.png|All Files (*.*)|*.*||";
	CFileDialog FileDialog(FALSE,"png",outputdir, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, Filters);
	if (FileDialog.DoModal() == IDOK)	
	{
		POSITION pos	=FileDialog.GetStartPosition();
		if(pos != NULL)
		{
			FileName = FileDialog.GetNextPathName(pos);
		}
	}
	return FileName;
}

bool ChildGraphFrame::GetPositionForPicture( __int64 &StartPosition, __int64 &EndPosition )
{
	ZWaveeditorDoc* pDoc = ((ZWaveeditorDoc*)GetActiveDocument());
	PictureRangeDialog PRD( pDoc->_script[ SelectedScenario ]->mygraphdata.GetTotalSize(), pDoc->_script[SelectedScenario]->GetCurrentTimeType() );
	INT_PTR ReturnedValue = PRD.DoModal();
	bool Result = false;
	switch ( ReturnedValue )
	{
	case -1:
		{
			AfxMessageBox("Dialog box was unable to be created!");
		}
	case IDOK:
		{
			StartPosition = PRD.GetStartPos();
			EndPosition = PRD.GetEndPos();;
			Result = true;
		}
	case IDCANCEL:
	default:
		{
		}
	}
	return Result;
}

void ChildGraphFrame::OnSizing(UINT fwSide, LPRECT pRect)
{
	CMDIChildWnd::OnSizing(fwSide, pRect);
	CRect framerect;
	CRect srect;
	CRect trect;

	ParentMainFrame *pMainFrame = (ParentMainFrame *) AfxGetMainWnd();
	pMainFrame->GetClientRect(&framerect);
	pMainFrame->m_wndStatusBar	.GetWindowRect(&srect);
	pMainFrame->m_wndToolBar	.GetWindowRect(&trect);
	int	height	=	framerect.Height()-srect.Height()*2-trect.Height();
	RECT	cs;
	cs.left		=	framerect.right / 4;
	cs.top		=	framerect.top;
	cs.right	=	framerect.right;
	cs.bottom	=	framerect.top + height - DEBUG_WINDOW_HEIGHT;
	MoveWindow(&cs);
}

void ChildGraphFrame::OnShowGrid()
{
	GetGraphView()->SetVisibleOrInvisibleGrid();
	GetGraphView()->Invalidate();
}